Implement global MSBuild defaults for [Projectable] options#191
Implement global MSBuild defaults for [Projectable] options#191
Conversation
…ce attribute handling
There was a problem hiding this comment.
Pull request overview
Adds support for project-wide defaults for [Projectable] options by flowing MSBuild global properties (CompilerVisibleProperty → build_property.*) into the generator and applying them as fallbacks when the attribute doesn’t specify an option.
Changes:
- Introduces
ProjectableGlobalOptionsand wires global analyzer config options into the incremental generator pipeline. - Updates attribute snapshotting to preserve “unset vs explicitly set” semantics (nullable option fields) so member-level settings can override global defaults.
- Adds generator tests that inject MSBuild global properties via
AnalyzerConfigOptionsProvider.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTestsBase.cs | Adds a new RunGenerator overload and helper types to inject MSBuild global properties in generator tests. |
| tests/EntityFrameworkCore.Projectables.Generator.Tests/GlobalOptionsTests.cs | New tests validating global defaults and member-level overrides for key [Projectable] options. |
| src/EntityFrameworkCore.Projectables.Generator/ProjectionExpressionGenerator.cs | Plumbs global options into the generator pipeline and execution path. |
| src/EntityFrameworkCore.Projectables.Generator/Models/ProjectableGlobalOptions.cs | New model that snapshots build_property.Projectables_* values from global analyzer config options. |
| src/EntityFrameworkCore.Projectables.Generator/Models/ProjectableAttributeData.cs | Changes option fields to nullable so absence can fall back to global defaults. |
| src/EntityFrameworkCore.Projectables.Generator/Interpretation/ProjectableInterpreter.cs | Resolves effective option values with precedence: attribute → global MSBuild default → hard-coded fallback. |
| src/EntityFrameworkCore.Projectables.Generator/Comparers/MemberDeclarationSyntaxAndCompilationEqualityComparer.cs | Includes global options in incremental equality/hashing so changes invalidate cached results correctly. |
| src/EntityFrameworkCore.Projectables.Abstractions/build/EntityFrameworkCore.Projectables.Abstractions.props | Adds CompilerVisibleProperty declarations (and placeholder properties) to expose MSBuild values to the compiler/generator. |
| src/EntityFrameworkCore.Projectables.Abstractions/EntityFrameworkCore.Projectables.Abstractions.csproj | Packs the new .props file into the NuGet package. |
| { | ||
| if (globalOptions.TryGetValue("build_property.Projectables_NullConditionalRewriteSupport", out var nullConditionalStr) | ||
| && !string.IsNullOrEmpty(nullConditionalStr) | ||
| && Enum.TryParse<NullConditionalRewriteSupport>(nullConditionalStr, ignoreCase: true, out var nullConditional)) |
There was a problem hiding this comment.
Projectables_NullConditionalRewriteSupport is parsed with Enum.TryParse, which will also accept numeric values (and potentially undefined enum values) as valid. That means a malformed MSBuild value like 999 would silently become an effective option rather than being treated as "not set". Consider validating with Enum.IsDefined (or rejecting numeric-only inputs) so malformed values are ignored consistently with the bool options tests.
| && Enum.TryParse<NullConditionalRewriteSupport>(nullConditionalStr, ignoreCase: true, out var nullConditional)) | |
| && Enum.TryParse<NullConditionalRewriteSupport>(nullConditionalStr, ignoreCase: true, out var nullConditional) | |
| && Enum.IsDefined(typeof(NullConditionalRewriteSupport), nullConditional)) |
...FrameworkCore.Projectables.Abstractions/EntityFrameworkCore.Projectables.Abstractions.csproj
Outdated
Show resolved
Hide resolved
…orkCore.Projectables.Abstractions.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Updated [EntityFrameworkCore.Projectables](https://github.com/EFNext/EntityFrameworkCore.Projectables) from 5.0.2 to 6.0.0. <details> <summary>Release notes</summary> _Sourced from [EntityFrameworkCore.Projectables's releases](https://github.com/EFNext/EntityFrameworkCore.Projectables/releases)._ ## 6.0.0 ## What's Changed ### Major changes * Add support for projectable method overloads by @PhenX in EFNext/EntityFrameworkCore.Projectables#143 * Add C#14 extension members by @PhenX in EFNext/EntityFrameworkCore.Projectables#148 * Support explicitly implemented interface members and default interface properties by @rhodon-jargon in EFNext/EntityFrameworkCore.Projectables#135 * Support block-bodied members with [Projectable] attribute by @Copilot in EFNext/EntityFrameworkCore.Projectables#152 * Add ExpandEnumMethods to expand enum extension calls into ternary expressions by @Copilot in EFNext/EntityFrameworkCore.Projectables#150 * Add support for pattern matching in various cases by @PhenX in EFNext/EntityFrameworkCore.Projectables#158 * Add support for projectable constructors by @PhenX in EFNext/EntityFrameworkCore.Projectables#161 * AOT-compatible static projection registry + SyntaxFactory-based emission by @Copilot in EFNext/EntityFrameworkCore.Projectables#166 * Improve UseMemberBody and add new diagnostics by @PhenX in EFNext/EntityFrameworkCore.Projectables#174 * Add code fixes for EFP0001, EFP0002 and EFP0008, with tests by @PhenX in EFNext/EntityFrameworkCore.Projectables#181 * Add a code fixer and a code refactorer to transform factory methods into constructors by @PhenX in EFNext/EntityFrameworkCore.Projectables#183 * Improve source generator and analyzer responsiveness by @PhenX in EFNext/EntityFrameworkCore.Projectables#171 * Docs website by @PhenX in EFNext/EntityFrameworkCore.Projectables#194 * Implement global MSBuild defaults for [Projectable] options by @koenbeuk in EFNext/EntityFrameworkCore.Projectables#191 ### Other changes * Check source generator output compilation by @PhenX in EFNext/EntityFrameworkCore.Projectables#156 * Fix GetImplementingProperty issue when using interfaces by @PhenX in EFNext/EntityFrameworkCore.Projectables#144 * Full qualification not needed anymore by @PhenX in EFNext/EntityFrameworkCore.Projectables#157 * Split generator tests in different classes by @PhenX in EFNext/EntityFrameworkCore.Projectables#162 * Refactor ExpressionSyntaxRewriter into focused partial class files by @Copilot in EFNext/EntityFrameworkCore.Projectables#163 * Update readme and add new test for constructors by @PhenX in EFNext/EntityFrameworkCore.Projectables#165 * Remove obsolete code by @PhenX in EFNext/EntityFrameworkCore.Projectables#167 * Add source generator self-benchmark covering all expression transformers by @Copilot in EFNext/EntityFrameworkCore.Projectables#168 * Fix null conditional rewrite generating invalid member access on nullable value types by @Copilot in EFNext/EntityFrameworkCore.Projectables#169 * Improve generator benchmark with more realistic scenario by @PhenX in EFNext/EntityFrameworkCore.Projectables#170 * Fix stale incremental generator cache when referenced types change in other source files by @Copilot in EFNext/EntityFrameworkCore.Projectables#172 * Add tests for properties with a getter and setter by @PhenX in EFNext/EntityFrameworkCore.Projectables#173 * UseMemberBody more strict with expressions by @PhenX in EFNext/EntityFrameworkCore.Projectables#175 * Add custom Copilot instructions by @PhenX in EFNext/EntityFrameworkCore.Projectables#177 * Reorganize generator project by @PhenX in EFNext/EntityFrameworkCore.Projectables#178 * Add closure resolution benchmark by @PhenX in EFNext/EntityFrameworkCore.Projectables#179 * Feature/optimize closures by @PhenX in EFNext/EntityFrameworkCore.Projectables#180 * Feature/optimize resolver by @PhenX in EFNext/EntityFrameworkCore.Projectables#182 * Update github project urls by @PhenX in EFNext/EntityFrameworkCore.Projectables#184 * Update deps by @PhenX in EFNext/EntityFrameworkCore.Projectables#185 * Remove obsolete verified files and name net8 files correctly by @PhenX in EFNext/EntityFrameworkCore.Projectables#186 * Remove all allocations when resolving and make it even faster by @PhenX in EFNext/EntityFrameworkCore.Projectables#189 * Add devcontainer configuration for C# (.NET) development by @koenbeuk in EFNext/EntityFrameworkCore.Projectables#190 **Full Changelog**: EFNext/EntityFrameworkCore.Projectables@v5.0.2...v6.0.0 Commits viewable in [compare view](EFNext/EntityFrameworkCore.Projectables@v5.0.2...v6.0.0). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: James Gunn <james@gunn.io>
Introduce global MSBuild defaults for [Projectable] options, enhancing attribute handling and allowing for project-wide configuration. This change enables the use of global settings while maintaining the ability to override them at the member level.
closes #133